import { Component, EventEmitter, Inject, Input, OnChanges, OnInit, Output, QueryList, SimpleChanges, ViewChildren } from '@angular/core';
import { timer } from 'rxjs';
import { Song } from 'src/app/services/data-types/common.types';
import { SongService } from 'src/app/services/song.service';
import { findIndex } from 'src/app/utils/array';
import { WyScrollComponent } from '../wy-scroll/wy-scroll.component';
import { BaseLyricLine, WyLyric } from './wy-lyric';
@Component({
  selector: 'app-wy-player-panel',
  templateUrl: './wy-player-panel.component.html',
  styleUrls: ['./wy-player-panel.component.less']
})
export class WyPlayerPanelComponent implements OnInit,OnChanges {
  @Input() songList!: Song[];
  @Input() currentSong!: Song;
  @Input() show!: boolean;
  @Input() playing!: boolean;

  @Output() onClose = new EventEmitter<void>();
  @Output() onChangeSong = new EventEmitter<Song>();
  @Output() onDeletSong = new EventEmitter<Song>();
  @Output() onClearSong = new EventEmitter<void>();
  @Output() onToInfo = new EventEmitter<[string, number]>();

  scrollY: number = 0;

  currentLineNum!: number;
  currentIndex!: number;
  currentLyric!: BaseLyricLine[];
  startLine: number = 3;

  private lyric!: WyLyric;
  private lyricRefs!: NodeList;

  @ViewChildren(WyScrollComponent) private wyScroll!: QueryList<WyScrollComponent>;
  constructor(
    private songService: SongService,
  ) { }

  ngOnInit(): void {
  }
  ngOnChanges(changes: SimpleChanges): void {
    if(changes['playing']){
      if(!changes['playing'].firstChange){
        this.lyric?.togglePlay(this.playing);
      }
    }
    if(changes['songList']){
      if(this.currentSong){
        this.upDateCurrentIndex();
      }
    }
    if(changes['currentSong']){
      if(this.currentSong){
        this.upDateCurrentIndex();
        this.upDateLyric();
        if(this.show){
          this.scrollToCurrent()
        }
      }else{
        this.resetLyric()
      }
    }
    if(changes['show']){
      if(!changes['show'].firstChange && this.show){
        this.wyScroll.first.refreshScroll()
        this.wyScroll.last.refreshScroll()
        timer(80).subscribe(()=>{
          if(this.show){
            this.scrollToCurrent(0)
          }
          if(this.lyricRefs){
            this.scrollToCurrentLyric(0)
          }
        })
      }
    }
  }

  private upDateCurrentIndex(){
    this.currentIndex = findIndex(this.songList, this.currentSong);
  }

  // 获取歌词
  private upDateLyric(){
    this.resetLyric();
    this.songService.getLyric(this.currentSong.id).subscribe(res => {
      this.lyric = new WyLyric(res)
      this.currentLyric = this.lyric.lines;
      this.wyScroll.last.scrollTo(0, 0);
      this.startLine = res.tlyric ? 1 : 3
      this.handlerLyric();
      if(this.playing){
        this.lyric.play()
      }
    })
  }
  private resetLyric(){
    if(this.lyric){
      this.lyric?.stop()
      let lyricData!: WyLyric;
      this.lyric = lyricData;
      this.currentLyric = []
      this.currentLineNum = 0;
      let lyricDate!: NodeList;
      this.lyricRefs = lyricDate;
    }
  }

  private handlerLyric(){
    this.lyric.handler.subscribe(({lineNum})=>{
      if(!this.lyricRefs){
        this.lyricRefs = this.wyScroll.last.el.nativeElement.querySelectorAll('ul li');
      }
      if(this.lyricRefs.length){
        this.currentLineNum = lineNum
        if(lineNum > this.startLine){
          this.scrollToCurrentLyric(300)
        }else{
          this.wyScroll.last.scrollTo(0, 0);
        }
      }
    })
  }

  seekLyric(time: number){
    if(this.lyric){
      this.lyric.seek(time);
    }
  }

  private scrollToCurrent(speed = 300){
    const songListRefs = this.wyScroll.first.el.nativeElement.querySelectorAll('ul li');
    if(songListRefs.length){
      const currentLi = <HTMLElement>songListRefs[this.currentIndex | 0]
      const offsetTop = currentLi.offsetTop;
      const offsetHeight = currentLi.offsetHeight;
      if((offsetTop - Math.abs(this.scrollY) > (offsetHeight * 5)) || (offsetTop < Math.abs(this.scrollY))){
        this.wyScroll.first.scrollToElement(currentLi, speed, false, false)
      }
    }
  }

  private scrollToCurrentLyric(speed = 300){
    const startLineNum = (this.currentLineNum - this.startLine >= 0 ? this.currentLineNum - this.startLine : 0)
    const targetLine = <HTMLElement>this.lyricRefs[startLineNum]
    if(targetLine){
      this.wyScroll.last.scrollToElement(targetLine, speed, false, false)
    }
  }
  toInfo(ent:MouseEvent,path:[string, number]){
    ent.stopPropagation()
    this.onToInfo.emit(path)
  }
}
